import requests
from fastapi import HTTPException

import config
import time

DASHSCOPE_API_KEY = config.OPENAI_API_KEY


def check_image_for_video(type: str, image_url: str = None, video_url: str = None):
    """
    检查图片是否适合生成视频
    Args:
        image_url (str): 输入图片的URL
    Returns:
        dict: API响应结果
    Raises:
        Exception: 当API请求失败时抛出异常
    """
    parameters={}
    input= {}
    match type:
        case "ANIMATE":
            model = "animate-anyone-detect-gen2"
            api_url = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/aa-detect"
            input["image_url"] = image_url
        case "EMO":
            model = "emo-detect-v1"
            api_url = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/face-detect"
            parameters["ratio"]="1:1"
            input["image_url"] = image_url
        case "LIVE":
            model = "liveportrait-detect"
            api_url = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/face-detect"
            input["image_url"] = image_url
        case "Motion":
            model = "motionshop-video-detect"
            api_url = "https://dashscope.aliyuncs.com/api/v1/services/aigc/video-generation/video-detect"
            input["video_url"] = video_url
            parameters["threshold"]=0.5
            parameters["min_area_ratio"]=0.01
        case _:
            raise HTTPException(status_code=400, detail="""
            type参数错误，仅支持：
            ANIMATE 舞动人像
            EMO 悦动人像, 
            LIVE 灵动人像,
            Motion 幻影人像
            """)
    headers = {
        "Authorization": f"Bearer {DASHSCOPE_API_KEY}",
        "Content-Type": "application/json"
    }

    payload = {
        "model": model,
        "input": input,
        "parameters": parameters
    }

    try:
        response = requests.post(api_url, headers=headers, json=payload)
        response.raise_for_status()  # 检查HTTP错误
        print(response.json())
        # 检查是否需要轮询任务状态
        if response.json().get("output", {}).get("task_status") in ["PENDING", "RUNNING"]:
            task_id = response.json()["output"]["task_id"]
            print("task_id", task_id)
            return poll_task_status(task_id)
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"API请求失败: {str(e)}")
        raise Exception(f"图片检测API调用失败: {str(e)}")


def poll_task_status(task_id: str, max_retries: int = 60) -> dict:
    """
    轮询任务状态直到完成
    Args:
        task_id (str): 任务ID
        max_retries (int): 最大重试次数，默认60次（5分钟）
    Returns:
        dict: 最终的API响应结果
    Raises:
        Exception: 当API请求失败或超时时抛出异常
    """
    headers = {
        "Authorization": f"Bearer {DASHSCOPE_API_KEY}",
        "Content-Type": "application/json"
    }
    
    retry_count = 0
    while retry_count < max_retries:
        try:
            response = requests.get(f"https://dashscope.aliyuncs.com/api/v1/tasks/{task_id}", headers=headers)
            response.raise_for_status()
            result = response.json()
            
            task_status = result.get("output", {}).get("task_status")
            if task_status not in ["PENDING", "RUNNING"]:
                return result
                
            time.sleep(5)  # 等待5秒后重试
            retry_count += 1
            
        except requests.exceptions.RequestException as e:
            print(f"轮询任务状态失败: {str(e)}")
            raise Exception(f"轮询任务状态失败: {str(e)}")
    
    raise Exception("任务轮询超时")


def call_third_party_attendance_api(api_url: str, headers: dict, json: dict):
    """
    统一的第三方API调用处理函数
    
    Args:
        api_url (str): API端点URL
        headers (dict): 请求头
        json (dict): 请求体
    Returns:
        dict: API响应结果
    Raises:
        Exception: 当API请求失败时抛出异常
    """
    try:
        response = requests.post(api_url, headers=headers, json=json)
        response.raise_for_status()
        result = response.json()

        # 检查是否需要轮询任务状态
        if result.get("output", {}).get("task_status") in ["PENDING", "RUNNING"]:
            task_id = result["output"]["task_id"]
            print("task_id", task_id)
            return poll_task_status(task_id)
        
        return result
    except requests.exceptions.RequestException as e:
        print(f"API请求失败: {str(e)}")
        raise Exception(f"API调用失败: {str(e)}")


def generate_action_for_video(video_url: str) -> dict:
    """从视频中提取动作模板"""
    headers = {
        "Authorization": f"Bearer {DASHSCOPE_API_KEY}",
        "X-DashScope-Async": "enable",
        "Content-Type": "application/json"
    }

    payload = {
        "model": "animate-anyone-template-gen2",
        "input": {
            "video_url": video_url
        },
        "parameters": {}
    }

    api_url = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/aa-template-generation/"
    result = call_third_party_attendance_api(api_url, headers, payload)
    return result.get("output", {}).get("template_id")


def generate_3d_role_for_video(image_url: str) -> dict:
    """从视频中提取动作模板"""
    headers = {
        "Authorization": f"Bearer {DASHSCOPE_API_KEY}",
        "X-DashScope-Async": "enable",
        "Content-Type": "application/json"
    }

    payload = {
        "model": "motionshop-gen3d",
        "input": {
            "image_url": image_url
        }
    }

    api_url = "https://dashscope.aliyuncs.com/api/v1/services/aigc/video-generation/3d-generation"
    result = call_third_party_attendance_api(api_url, headers, payload)
    return result.get("output", {}).get("ply_url")


def create_video_by_type(type:str, json_post:dict) -> dict:
    headers = {
        "Authorization": f"Bearer {DASHSCOPE_API_KEY}",
        "X-DashScope-Async": "enable",
        "Content-Type": "application/json"
    }
    api_url = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/video-synthesis/"

    match type:
        case "ANIMATE": # 根据人像图片和动作视频生成视频
            image_url = json_post.get("image_url")
            if not image_url:
                raise HTTPException(status_code=400, detail="缺少image_url参数")
            template_id = json_post.get("template_id")
            if not template_id:
                raise HTTPException(status_code=400, detail="缺少template_id参数")
            payload = {
                "model": "animate-anyone-gen2",
                "input": {
                    "image_url": image_url,
                    "template_id": template_id
                },
                "parameters": {
                    "use_ref_img_bg": "true",
                    "video_ratio": "9:16"
                }
            }
            result = call_third_party_attendance_api(api_url, headers, payload)
            
            # 如果API调用成功且返回了视频URL
            if result and result.get("output", {}).get("url"):
                # 使用统一的文件名生成逻辑
                from common.comm_utils import get_file_name
                
                # 根据不同类型生成描述
                description = "舞动人像视频"
                
                # 生成文件名
                file_name = get_file_name(description)
                if not file_name.endswith('.mp4'):
                    file_name += '.mp4'
                
                result["output"]["file_name"] = file_name
            
            return result
        case "EMO": # 根据人像图片和音频生成视频
            image_url = json_post.get("image_url")
            if not image_url:
                raise HTTPException(status_code=400, detail="缺少image_url参数")
            audio_id = json_post.get("audio_id")
            face_bbox = json_post.get("face_bbox")
            ext_bbox = json_post.get("ext_bbox")
            if not audio_id:
                raise HTTPException(status_code=400, detail="缺少audio_id参数")
            payload = {
                "model": "emo-v1",
                "input": {
                    "image_url": image_url,
                    "audio_id": audio_id,
                    "face_bbox": face_bbox,
                    "ext_bbox": ext_bbox
                },
                "parameters": {
                    "style_level": "normal"
                }
            }
            result = call_third_party_attendance_api(api_url, headers, payload)
            
            # 如果API调用成功且返回了视频URL
            if result and result.get("output", {}).get("url"):
                # 使用统一的文件名生成逻辑
                from common.comm_utils import get_file_name
                
                # 根据不同类型生成描述
                description = "悦动人像视频"
                
                # 生成文件名
                file_name = get_file_name(description)
                if not file_name.endswith('.mp4'):
                    file_name += '.mp4'
                
                result["output"]["file_name"] = file_name
            
            return result
        case "LIVE": # 根据虚拟肖像图片和音频生成视频
            image_url = json_post.get("image_url")
            if not image_url:
                raise HTTPException(status_code=400, detail="缺少image_url参数")
            audio_url = json_post.get("audio_url")
            if not audio_url:
                raise HTTPException(status_code=400, detail="缺少audio_url参数")
            payload = {
                "model": "liveportrait",
                "input": {
                    "image_url": image_url,
                    "audio_url": audio_url
                },
                "parameters": {
                    "template_id": "normal",
                    "eye_move_freq": 0.5,
                    "video_fps": 30,
                    "mouth_move_strength": 1,
                    "paste_back": "true",
                    "head_move_strength": 0.7
                }
            }

            result = call_third_party_attendance_api(api_url, headers, payload)
            
            # 如果API调用成功且返回了视频URL
            if result and result.get("output", {}).get("url"):
                # 使用统一的文件名生成逻辑
                from common.comm_utils import get_file_name
                
                # 根据不同类型生成描述
                description = "灵动人像视频"
                
                # 生成文件名
                file_name = get_file_name(description)
                if not file_name.endswith('.mp4'):
                    file_name += '.mp4'
                
                result["output"]["file_name"] = file_name
            
            return result
        case "VIDEO": # 根据音频和视频生成对口型的视频
            video_url = json_post.get("video_url")
            audio_url = json_post.get("audio_url")
            if not video_url or not audio_url:
                raise HTTPException(status_code=400, detail="缺少video_url或audio_url参数")
            payload = {
                "model": "videoretalk",
                "input": {
                    "video_url": video_url,
                    "audio_url": audio_url,
                    "ref_image_url": ""
                },
                "parameters": {
                    "video_extension": "false"
                }
            }

            result = call_third_party_attendance_api(api_url, headers, payload)
            
            # 如果API调用成功且返回了视频URL
            if result and result.get("output", {}).get("url"):
                # 使用统一的文件名生成逻辑
                from common.comm_utils import get_file_name
                
                # 根据不同类型生成描述
                description = "声动人像视频"
                
                # 生成文件名
                file_name = get_file_name(description)
                if not file_name.endswith('.mp4'):
                    file_name += '.mp4'
                
                result["output"]["file_name"] = file_name
            
            return result
        case "Motion": # 根据视频生成3D形象的视频
            video_url = json_post.get("video_url")
            frame_index = json_post.get("frame_index")
            bbox = json_post.get("bbox")
            replacement_id = json_post.get("replacement_id")

            if not video_url:
                raise HTTPException(status_code=400, detail="缺少video_url参数")
            payload = {
                "model": "motionshop-synthesis",
                "input": {
                    "video_url": video_url,
                    "frame_index": frame_index,
                    "bbox": bbox,
                    "replacement_id": replacement_id
                }
            }

            result = call_third_party_attendance_api(api_url, headers, payload)
            
            # 如果API调用成功且返回了视频URL
            if result and result.get("output", {}).get("url"):
                # 使用统一的文件名生成逻辑
                from common.comm_utils import get_file_name
                
                # 根据不同类型生成描述
                description = "幻影人像视频"
                
                # 生成文件名
                file_name = get_file_name(description)
                if not file_name.endswith('.mp4'):
                    file_name += '.mp4'
                
                result["output"]["file_name"] = file_name
            
            return result
        case _:
            raise HTTPException(status_code=400, detail="""
            type参数错误，仅支持：
            ANIMATE 舞动人像
            EMO 悦动人像, 
            LIVE 灵动人像
            VIDEO 声动人像
            """)

